#include "api_data.h"

namespace Api
{

#pragma region HourData

    HourData::HourData(){};
    void HourData::load(int timestamp, float temp, String weather_name, String weather_icon, float pop)
    {
        this->timestamp = timestamp;
        this->temp = temp;
        this->weather_name = weather_name;
        this->weather_icon = weather_icon;
        this->str_hour = Helper::strtotime("%I%p", timestamp);
        this->pop = pop;
        this->popPercent = (int)(pop * 100);
        // Serial2.printf("hourData[ts]: %d \n", this->timestamp);
        // Serial2.printf("hourData[temp]: %3.2f \n", this->temp);
        // Serial2.printf("hourData[name]: %s \n", this->weather_name);
        // Serial2.printf("hourData[icon]: %s \n", this->weather_icon.c_str());
        // Serial2.printf("hourData[hour]: %s \n", this->str_hour.c_str());
    };
    String HourData::getStrHour()
    {
        return str_hour;
    };
    float HourData::getTemp()
    {
        return temp;
    };
    String HourData::getWeatherName()
    {
        return weather_name;
    };
    String HourData::getWeatherIcon()
    {
        return weather_icon;
    };
    float HourData::getPop()
    {
        return pop;
    };
    int HourData::getPopPercent()
    {
        return popPercent;
    };

#pragma endregion

#pragma region DayData

    DayData::DayData(){};
    void DayData::load(int timestamp, float tempMin, float tempMax, String weather_name, String weather_icon, float pop)
    {
        this->timestamp = timestamp;
        this->strWeek = Helper::strtotime("%a", timestamp);
        this->tempMin = tempMin;
        this->tempMax = tempMax;
        this->weather_name = weather_name;
        this->weather_icon = weather_icon;
        this->pop = pop;
        this->popPercent = (int)(pop * 100);
    }
    String DayData::getStrWeek()
    {
        return strWeek;
    }
    float DayData::getTempMin()
    {
        return tempMin;
    };
    float DayData::getTempMax()
    {
        return tempMax;
    };
    String DayData::getWeatherName()
    {
        return weather_name;
    };
    String DayData::getWeatherIcon()
    {
        return weather_icon;
    };
    float DayData::getPop()
    {
        return pop;
    };
    int DayData::getPopPercent()
    {
        return popPercent;
    };

#pragma endregion

#pragma region TodayData

    TodayData::TodayData(){};
    void TodayData::load(int timestamp, float temp, String weather_name, String weather_icon,
                                 float pop, int pressure, int humidity, int wind_speed)
    {
        this->timestamp = timestamp;
        this->strDay = Helper::strtotime("%b %d %R", timestamp);
        this->temp = temp;
        this->weather_name = weather_name;
        this->weather_icon = weather_icon;
        this->pop = pop;
        this->popPercent = (int)(pop * 100);
        this->pressure = pressure;
        this->humidity = humidity;
        this->wind_speed = wind_speed;
    };
    int TodayData::getTimestamp()
    {
        return timestamp;
    };
    String TodayData::getStrDay()
    {
        return strDay;
    };
    float TodayData::getTemp()
    {
        return temp;
    };
    String TodayData::getWeatherName()
    {
        return weather_name;
    };
    String TodayData::getWeatherIcon()
    {
        return weather_icon;
    };
    float TodayData::getPop()
    {
        return pop;
    };
    int TodayData::getPopPercent()
    {
        return popPercent;
    };
    int TodayData::getPressure()
    {
        return pressure;
    };
    int TodayData::getHumidity()
    {
        return humidity;
    };
    int TodayData::getWindSpeed()
    {
        return wind_speed;
    };

#pragma endregion

#pragma region HardwareData

    HardwareData::HardwareData(){};
    void HardwareData::load(float battery_percent, float temperature, float humidity)
    {
        this->batteryPercent = battery_percent;
        this->temperature = temperature;
        this->humidity = humidity;
    };
    float HardwareData::getBatteryPercent()
    {
        return batteryPercent;
    };
    float HardwareData::getTemperature()
    {
        return temperature;
    };
    float HardwareData::getHumidity()
    {
        return humidity;
    };

#pragma endregion

#pragma region Data

    Data::Data(){};
    void Data::loadWeather(DynamicJsonDocument doc)
    {
        JsonObject docToday = doc["current"];
        JsonObject docTodayWeather = docToday["weather"][0];
        JsonArray docHours = doc["hourly"];
        JsonArray docDays = doc["daily"];

        int _dataTodayTimestamp = docToday["dt"].as<int>();
        todayData.load(
            _dataTodayTimestamp,
            docToday["temp"].as<float>(),
            docTodayWeather["main"].as<String>(),
            docTodayWeather["icon"].as<String>(),
            docToday["pop"].as<float>(),
            docToday["pressure"].as<int>(),
            docToday["humidity"].as<int>(),
            docToday["wind_speed"].as<int>());

        int _sizeOfdocHours = docHours.size();
        for (int i = 0; i < _sizeOfdocHours; i++)
        {
            JsonObject _dataHour = docHours[i];
            int _dataHourTimestamp = _dataHour["dt"].as<int>();
            HourData _hourData;
            _hourData.load(
                _dataHourTimestamp,
                _dataHour["temp"].as<float>(),
                _dataHour["weather"][0]["main"].as<String>(),
                _dataHour["weather"][0]["icon"].as<String>(),
                _dataHour["pop"].as<float>());
            hoursData.push_back(_hourData);
        }

        int _sizeOfdocdays = docDays.size();
        for (int i = 0; i < _sizeOfdocdays; i++)
        {
            JsonObject _dataDay = docDays[i];
            int _dataDayTimestamp = _dataDay["dt"].as<int>();
            DayData _hourDay;
            _hourDay.load(
                _dataDayTimestamp,
                _dataDay["temp"]["min"].as<float>(),
                _dataDay["temp"]["max"].as<float>(),
                _dataDay["weather"][0]["main"].as<String>(),
                _dataDay["weather"][0]["icon"].as<String>(),
                _dataDay["pop"].as<float>());
            daysData.push_back(_hourDay);
        }
    };
    void Data::loadHardware(Helper::Hardware hardware)
    {
        hardwareData.load(hardware);
    };
    TodayData Data::getTodayData()
    {
        return todayData;
    };
    HardwareData Data::getHardwareData()
    {
        return hardwareData;
    };
    std::vector<HourData> Data::getHoursData()
    {
        return hoursData;
    };
    std::vector<DayData> Data::getDaysData()
    {
        return daysData;
    };

#pragma endregion

}
